home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / C / Frameworks / TransSkel 3.24 / Demos / C Demos / ThreadDemo / ThreadDemo.c next >
Encoding:
C/C++ Source or Header  |  1995-07-23  |  6.8 KB  |  332 lines  |  [TEXT/CWIE]

  1. /*
  2.  * Threads - TransSkel Thread Manager demonstration application
  3.  *
  4.  * This is a very simple-minded demonstration. It puts up a single
  5.  * window that draws a horizontal line, a vertical line, and an oval
  6.  * whose horizontal and vertical axes are the same length as the current
  7.  * lengths of the horizontal and vertical lines.  Each of the lines
  8.  * and the oval are drawn independently, using three threads.  In order
  9.  * to emphasize the independent nature of the three threads, the
  10.  * graphical object draw by each updates at a different rate.
  11.  *
  12.  * 23 Jul 95 Version 1.00, Paul DuBois
  13.  */
  14.  
  15. # include    "TransSkel.h"
  16.  
  17. # include    <Threads.h>
  18.  
  19.  
  20. /* window positioning ratios */
  21.  
  22. # define    hRatio    FixRatio (1, 2)
  23. # define    vRatio    FixRatio (1, 5)
  24.  
  25. /*
  26.  * Resource numbers
  27.  */
  28.  
  29. # define    aboutAlrtRes    1000                    /* About box */
  30. # define    errAlrtRes        1001                    /* error alert */
  31. # define    fileMenuNum        (skelAppleMenuID + 1)    /* File menu */
  32.  
  33. /* error string resource numbers */
  34.  
  35. # define    noThreadManager 1000
  36. # define    noThread        1001
  37.  
  38.  
  39. # define    windowTitle        "\pThreadDemo"
  40. # define    windowWidth        300
  41. # define    windowHeight    120
  42.  
  43. # define    maxLineLen        100
  44.  
  45. /* thread update times */
  46.  
  47. # define    thread1Update    1L
  48. # define    thread2Update    3L
  49. # define    thread3Update    2L
  50.  
  51. /* file menu item numbers */
  52.  
  53. enum
  54. {
  55.     quit = 1
  56. };
  57.  
  58.  
  59. static MenuHandle    fileMenu;
  60.  
  61. static short    length1 = 0;    /* horizontal line length */
  62. static short    length2 = 0;    /* vertical line length */
  63.  
  64.  
  65. static void
  66. Die (short strNum)
  67. {
  68. StringHandle    h;
  69.  
  70.     h = GetString (strNum);
  71.     if (h != (StringHandle) nil)
  72.     {
  73.         HLock ((Handle) h);
  74.         ParamText (*h, nil, nil, nil);
  75.         HUnlock ((Handle) h);
  76.     }
  77.     else
  78.         ParamText ("\pAn unknown error occurred.", nil, nil, nil);
  79.  
  80.     (void) SkelAlert (errAlrtRes, SkelDlogFilter (nil, true),
  81.                                         skelPositionOnParentDevice);
  82.     SkelRmveDlogFilter ();
  83.     SkelCleanup ();
  84.     ExitToShell ();
  85. }
  86.  
  87.  
  88. /* -------------------------------------------------------------------- */
  89. /*                        Menu handling procedures                        */
  90. /* -------------------------------------------------------------------- */
  91.  
  92.  
  93. /*
  94.  * Handle selection of "About Hello..." item from Apple menu
  95.  */
  96.  
  97. static pascal void
  98. DoAppleMenu (short item)
  99. {
  100.     (void) SkelAlert (aboutAlrtRes, SkelDlogFilter (nil, true),
  101.                                         skelPositionOnParentDevice);
  102.     SkelRmveDlogFilter ();
  103. }
  104.  
  105.  
  106. /*
  107.  * Process selection from File menu.
  108.  */
  109.  
  110. static pascal void
  111. DoFileMenu (short item)
  112. {
  113.     switch (item)
  114.     {
  115.     case quit:
  116.         SkelStopEventLoop ();
  117.         break;
  118.     }
  119. }
  120.  
  121.  
  122. /*
  123.  * Initialize menus.  Tell TransSkel to process the Apple menu
  124.  * automatically, and associate the proper procedure with the
  125.  * File menu.
  126.  *
  127.  * \311 is the ellipsis character.
  128.  */
  129.  
  130. static void
  131. SetupMenus (void)
  132. {
  133.     SkelApple ("\pAbout ThreadDemo\311", DoAppleMenu);
  134.     fileMenu = NewMenu (fileMenuNum, "\pFile");
  135.     AppendMenu (fileMenu, "\pQuit/Q");
  136.     (void) SkelMenu (fileMenu, DoFileMenu, nil, false, false);
  137.  
  138.     DrawMenuBar ();
  139. }
  140.  
  141.  
  142. /* -------------------------------------------------------------------- */
  143. /*                    Window handling procedures                            */
  144. /* -------------------------------------------------------------------- */
  145.  
  146.  
  147. static pascal void
  148. Clobber (void)
  149. {
  150. WindowPtr    w;
  151.  
  152.     GetPort (&w);
  153.     DisposeWindow (w);
  154.  
  155.     /* should really dispose of threads here */
  156. }
  157.  
  158.  
  159. /* -------------------------------------------------------------------- */
  160. /*                    Thread handling procedures                            */
  161. /* -------------------------------------------------------------------- */
  162.  
  163.  
  164.  
  165. static pascal void *
  166. DoThread1 (void *threadParam)
  167. {
  168. static long        refTime = 0L;
  169. static long        delta = 4L;
  170.  
  171.     while (1)
  172.     {
  173.         if (TickCount () >= refTime)
  174.         {
  175.             PenMode (patBic);
  176.             MoveTo (60 - maxLineLen/2, 60);
  177.             LineTo (60 + maxLineLen/2, 60);
  178.             PenNormal ();
  179.             MoveTo (60 - length1/2, 60);
  180.             LineTo (60 + length1/2, 60);
  181.             if (delta > 0)
  182.             {
  183.                 if (length1 >= maxLineLen)
  184.                     delta = -delta;
  185.             }
  186.             else
  187.             {
  188.                 if (length1 <= 0)
  189.                     delta = -delta;
  190.             }
  191.             length1 += delta;
  192.             refTime = TickCount() + thread1Update;
  193.         }
  194.         (void) YieldToAnyThread ();
  195.     }
  196.     return (nil);        /* will never be reached */
  197. }
  198.  
  199.  
  200. static pascal void *
  201. DoThread2 (void *threadParam)
  202. {
  203. static long        refTime = 0L;
  204. static long        delta = 4L;
  205.  
  206.     while (1)
  207.     {
  208.         if (TickCount () >= refTime)
  209.         {
  210.             PenMode (patBic);
  211.             MoveTo (150, 60 - maxLineLen/2);
  212.             LineTo (150, 60 + maxLineLen/2);
  213.             PenNormal ();
  214.             MoveTo (150, 60 - length2/2);
  215.             LineTo (150, 60 + length2/2);
  216.             if (delta > 0)
  217.             {
  218.                 if (length2 >= maxLineLen)
  219.                     delta = -delta;
  220.             }
  221.             else
  222.             {
  223.                 if (length2 <= 0)
  224.                     delta = -delta;
  225.             }
  226.             length2 += delta;
  227.             refTime = TickCount() + thread2Update;
  228.         }
  229.         (void) YieldToAnyThread ();
  230.     }
  231.     return (nil);        /* will never be reached */
  232. }
  233.  
  234.  
  235. /*
  236.  * Draw an oval with the dimensions of the horizontal and vertical lines
  237.  * being drawn in threads 1 and 2.
  238.  */
  239.  
  240. static pascal void *
  241. DoThread3 (void *threadParam)
  242. {
  243. static long        refTime = 0L;
  244. static Rect        r = { 0, 0, 0, 0 };
  245.  
  246.     while (1)
  247.     {
  248.         if (TickCount () >= refTime)
  249.         {
  250.             EraseOval (&r);
  251.             SetRect (&r, 0, 0, length1, length2);
  252.             OffsetRect (&r, 240 - length1/2, 60 - length2/2);
  253.             FrameOval (&r);
  254.             refTime = TickCount() + thread3Update;
  255.         }
  256.         (void) YieldToAnyThread ();
  257.     }
  258.     return (nil);        /* will never be reached */
  259. }
  260.  
  261.  
  262. /*
  263.  * Create window and install handler for it
  264.  */
  265.  
  266. static void
  267. WindInit (void)
  268. {
  269. WindowPtr    w;
  270. Rect        bounds;
  271. ThreadID    dummyID;
  272.  
  273.     SetRect (&bounds, 0, 0, windowWidth, windowHeight);
  274.     if (SkelQuery (skelQHasColorQD))
  275.     {
  276.         w = NewCWindow (nil, &bounds, windowTitle, false,
  277.                         noGrowDocProc, (WindowPtr) -1, false, 0L);
  278.     }
  279.     else
  280.     {
  281.         w = NewWindow (nil, &bounds, windowTitle, false,
  282.                         noGrowDocProc, (WindowPtr) -1, false, 0L);
  283.     }
  284.     SkelPositionWindow (w, skelPositionOnMainDevice,
  285.                                     FixRatio (1, 2), FixRatio (1,5));
  286.     (void) SkelWindow (w, nil, nil, nil, nil, nil, Clobber, nil, false);
  287.  
  288.     SelectWindow (w);
  289.     ShowWindow (w);
  290.     SkelDoUpdates ();
  291.     SkelDoEvents (updateMask + activMask);
  292.  
  293.     if (NewThread (kCooperativeThread, DoThread1, nil, 0L,
  294.                     kCreateIfNeeded, nil, &dummyID) != noErr)
  295.     {
  296.         Die (noThread);
  297.     }
  298.     if (NewThread (kCooperativeThread, DoThread2, nil, 0L,
  299.                     kCreateIfNeeded, nil, &dummyID) != noErr)
  300.     {
  301.         Die (noThread);
  302.     }
  303.     if (NewThread (kCooperativeThread, DoThread3, nil, 0L,
  304.                     kCreateIfNeeded, nil, &dummyID) != noErr)
  305.     {
  306.         Die (noThread);
  307.     }
  308. }
  309.  
  310.  
  311. /* -------------------------------------------------------------------- */
  312. /*                                    Main                                */
  313. /* -------------------------------------------------------------------- */
  314.  
  315.  
  316. void
  317. main (void)
  318. {
  319. long    time;
  320.  
  321.     SkelInit ((SkelInitParamsPtr) nil);        /* initialize */
  322.     if (!SkelQuery (skelQHasThreads))
  323.         Die (noThreadManager);
  324.     SetupMenus ();                            /* install menu handlers */
  325.     WindInit();                                /* install window handler */
  326.     SkelGetWaitTimes (&time, nil);            /* set background wait time */
  327.     SkelSetWaitTimes (time, time);            /* to same as foreground time */
  328.     SkelSetThreadTimes (1L, 1L);
  329.     SkelEventLoop ();                        /* loop 'til Quit selected */
  330.     SkelCleanup ();                            /* clean up */
  331. }
  332.